namespace TSL.Utility.Json
{
    using System;
    using System.Globalization;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Xml;

    public sealed class JavaScriptUtil
    {
        public static XmlDocument ConvertIJavaScriptObjectToXml(IJavaScriptObject o)
        {
            XmlDocument document = new XmlDocument();
            document.LoadXml("<root/>");
            SerializeToAjaxXml(document.DocumentElement, o);
            return document;
        }

        public static IJavaScriptObject ConvertXmlToIJavaScriptObject(XmlDocument doc)
        {
            if (((doc == null) || (doc.DocumentElement == null)) || (doc.DocumentElement.ChildNodes.Count != 1))
            {
                return null;
            }
            return DeserialzeFromAjaxXml(doc.DocumentElement.ChildNodes[0]);
        }

        internal static IJavaScriptObject DeserialzeFromAjaxXml(XmlNode n)
        {
            switch (n.Name)
            {
                case "array":
                {
                    JavaScriptArray array = new JavaScriptArray();
                    foreach (XmlNode node in n.ChildNodes)
                    {
                        array.Add(DeserialzeFromAjaxXml(node));
                    }
                    return array;
                }
                case "boolean":
                    return new JavaScriptBoolean(n.InnerText == "true");

                case "number":
                {
                    JavaScriptNumber number = new JavaScriptNumber();
                    number.Append(n.InnerText);
                    return number;
                }
                case "string":
                {
                    JavaScriptString str = new JavaScriptString();
                    str.Append(n.InnerText);
                    return str;
                }
                case "object":
                {
                    JavaScriptObject obj2 = new JavaScriptObject();
                    foreach (XmlNode node2 in n.SelectNodes("property"))
                    {
                        if ((node2.Attributes["name"] != null) && (node2.ChildNodes.Count == 1))
                        {
                            obj2.Add(node2.Attributes["name"].Value, DeserialzeFromAjaxXml(node2.ChildNodes[0]));
                        }
                    }
                    return obj2;
                }
            }
            return null;
        }

        internal static string GetClientNamespaceRepresentation(string ns)
        {
            if (ns == null)
            {
                return "";
            }
            StringBuilder builder = new StringBuilder();
            string[] strArray = ns.Split(new char[] { '.' });
            if (strArray.Length <= 1)
            {
                return "";
            }
            string str = strArray[0];
            builder.Append("if(typeof " + str + " == \"undefined\") " + str + "={};\r\n");
            for (int i = 1; i < strArray.Length; i++)
            {
                str = str + "." + strArray[i];
                builder.Append("if(typeof " + str + " == \"undefined\") " + str + "={};\r\n");
            }
            return builder.ToString();
        }

        public static IJavaScriptObject GetIJavaScriptObjectFromXmlNode(XmlNode n)
        {
            if (n == null)
            {
                return null;
            }
            Regex regex = new Regex(@"\w+|\W+", RegexOptions.Compiled);
            JavaScriptObject obj2 = new JavaScriptObject();
            if (n.NodeType == XmlNodeType.Element)
            {
                for (int i = 0; i < n.Attributes.Count; i++)
                {
                    obj2.Add("@" + n.Attributes[i].Name, new JavaScriptString(n.Attributes[i].Value));
                }
                if (n.FirstChild != null)
                {
                    XmlNode node;
                    int num2 = 0;
                    bool flag = false;
                    for (node = n.FirstChild; node != null; node = node.NextSibling)
                    {
                        if (node.NodeType == XmlNodeType.Element)
                        {
                            flag = true;
                        }
                        if ((node.NodeType == XmlNodeType.Text) && regex.IsMatch(node.InnerText))
                        {
                            num2++;
                        }
                    }
                    if (flag)
                    {
                        if (num2 < 2)
                        {
                            for (node = n.FirstChild; node != null; node = node.NextSibling)
                            {
                                if (node.NodeType == XmlNodeType.Text)
                                {
                                    obj2.Add("#text", new JavaScriptString(node.InnerText));
                                }
                                else if (obj2.Contains(node.Name))
                                {
                                    if (obj2[node.Name] is JavaScriptArray)
                                    {
                                        ((JavaScriptArray) obj2[node.Name]).Add(GetIJavaScriptObjectFromXmlNode(node));
                                    }
                                    else
                                    {
                                        IJavaScriptObject obj3 = obj2[node.Name];
                                        JavaScriptArray array = new JavaScriptArray();
                                        array.Add(obj3);
                                        array.Add(GetIJavaScriptObjectFromXmlNode(node));
                                        obj2[node.Name] = array;
                                    }
                                }
                                else
                                {
                                    obj2.Add(node.Name, GetIJavaScriptObjectFromXmlNode(node));
                                }
                            }
                        }
                    }
                    else if (num2 > 0)
                    {
                        if (n.Attributes.Count == 0)
                        {
                            return new JavaScriptString(n.InnerText);
                        }
                        obj2.Add("#text", new JavaScriptString(n.InnerText));
                    }
                }
                if ((n.Attributes.Count == 0) && (n.FirstChild == null))
                {
                    return new JavaScriptString(n.InnerText);
                }
                return obj2;
            }
            if (n.NodeType != XmlNodeType.Document)
            {
                throw new NotSupportedException("Unhandled node type '" + n.NodeType + "'.");
            }
            return GetIJavaScriptObjectFromXmlNode(((XmlDocument) n).DocumentElement);
        }

        public static string QuoteHtmlAttribute(string s)
        {
            return QuoteString(s, '\'').Replace("\"", "&#34;");
        }

        public static string QuoteString(string s)
        {
            return QuoteString(s, '"');
        }

        internal static string QuoteString(string s, char quoteChar)
        {
            StringBuilder sb = new StringBuilder();
            QuoteString(s, quoteChar, sb);
            return sb.ToString();
        }

        public static void QuoteString(string s, StringBuilder sb)
        {
            QuoteString(s, '"', sb);
        }

        internal static void QuoteString(string s, char quoteChar, StringBuilder sb)
        {
            if ((s == null) || ((s.Length == 1) && (s[0] == '\0')))
            {
                sb.Append(new string(quoteChar, 2));
            }
            else
            {
                int length = s.Length;
                sb.EnsureCapacity((sb.Length + s.Length) + 2);
                sb.Append(quoteChar);
                for (int i = 0; i < length; i++)
                {
                    char ch = s[i];
                    switch (ch)
                    {
                        case '\b':
                        {
                            sb.Append(@"\b");
                            continue;
                        }
                        case '\t':
                        {
                            sb.Append(@"\t");
                            continue;
                        }
                        case '\n':
                        {
                            sb.Append(@"\n");
                            continue;
                        }
                        case '\f':
                        {
                            sb.Append(@"\f");
                            continue;
                        }
                        case '\r':
                        {
                            sb.Append(@"\r");
                            continue;
                        }
                        case '\\':
                        {
                            sb.Append(@"\\");
                            continue;
                        }
                    }
                    if (ch < ' ')
                    {
                        sb.Append(@"\u");
                        sb.Append(((int) ch).ToString("x4", CultureInfo.InvariantCulture));
                    }
                    else if (ch == quoteChar)
                    {
                        sb.Append(@"\");
                        sb.Append(ch);
                    }
                    else
                    {
                        sb.Append(ch);
                    }
                }
                sb.Append(quoteChar);
            }
        }

        internal static void SerializeToAjaxXml(XmlNode n, IJavaScriptObject o)
        {
            XmlElement element;
            if (o is JavaScriptArray)
            {
                element = n.OwnerDocument.CreateElement("array");
                foreach (IJavaScriptObject obj2 in (JavaScriptArray) o)
                {
                    SerializeToAjaxXml(element, obj2);
                }
                n.AppendChild(element);
            }
            else if (o is JavaScriptBoolean)
            {
                element = n.OwnerDocument.CreateElement("boolean");
                element.InnerText = (o is JavaScriptBoolean) ? "true" : "false";
                n.AppendChild(element);
            }
            else if (o is JavaScriptNumber)
            {
                element = n.OwnerDocument.CreateElement("number");
                element.InnerText = o.ToString();
                n.AppendChild(element);
            }
            else if (o is JavaScriptString)
            {
                element = n.OwnerDocument.CreateElement("string");
                element.InnerText = o.ToString();
                n.AppendChild(element);
            }
            else if (o is JavaScriptObject)
            {
                element = n.OwnerDocument.CreateElement("object");
                foreach (string str in ((JavaScriptObject) o).Keys)
                {
                    XmlElement newChild = n.OwnerDocument.CreateElement("property");
                    newChild.SetAttribute("name", str);
                    element.AppendChild(newChild);
                    SerializeToAjaxXml(newChild, ((JavaScriptObject) o)[str]);
                }
                n.AppendChild(element);
            }
        }
    }
}

